package com.fat.service.impl;

import com.fat.contains.ContainsStatus;
import com.fat.mapper.UserMapper;
import com.fat.pojo.Result;
import com.fat.pojo.User;
import com.fat.service.UserService;
import com.fat.utils.JwtUtil;
import com.fat.utils.Md5Util;
import com.fat.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public User findByUsername(String username) {
        return userMapper.findByUsername(username);
    }

    @Override
    public void register(String username, String password) {
        //加密密码
        String md5String = Md5Util.getMD5String(password);
        userMapper.register(username, md5String);
    }

    @Override
    public Result login(String username, String password) {
        //判断账号是否存在
        User loginUser = userMapper.findByUsername(username);
        if (Objects.isNull(loginUser)) {
            return Result.error(ContainsStatus.USER_USERNAME_NOT_EXIT);
        }
        //判断密码是否正确，密码需要加密后再比较
        if (StringUtils.pathEquals(loginUser.getPassword(), Md5Util.getMD5String(password))) {
            Map<String, Object> claims = new HashMap<>();
            claims.put("id", loginUser.getId());
            claims.put("username", loginUser.getUsername());
            //生成JWT
            String token = JwtUtil.genToken(claims);
            //将Token存入Redis中，时间为12小时
            redisTemplate.opsForValue().set(ContainsStatus.REDIS_USER_PREFIX+loginUser.getId(),token, 12, TimeUnit.HOURS);
            //返回
            return Result.success(token);
        }

        return Result.error(ContainsStatus.USER_PASSWORD_ERROR);
    }

    @Override
    public Result getUserInfo() {
        //从ThreadLocal中获取用户信息
        Map<String, Object> map = ThreadLocalUtil.get();
        //根据token中获取的username查值
        User user = userMapper.findByUsername(map.get("username").toString());
        //返回用户信息
        return Result.success(user);
    }

    @Override
    public Result update(User user) {
        //判断用户对象是否为空
        if (Objects.isNull(user)) {
            return Result.error(ContainsStatus.USER_UPDATE_ERROR);
        } else {
            userMapper.update(user);
            return Result.success();
        }
    }

    @Override
    public Result updateAvatar(String avatarUrl) {
        //从ThreadLocal中获取用户信息
        Map<String, Object> map = ThreadLocalUtil.get();
        //根据token中获取的username查值
        User user = userMapper.findByUsername(map.get("username").toString());
        //设置头像
        user.setUserPic(avatarUrl);
        //更新
        userMapper.update(user);
        return Result.success();
    }

    @Override
    public Result updatePwd(String oldPwd, String newPwd, String rePwd) {
        //校验参数
        if (!StringUtils.hasLength(oldPwd) || !StringUtils.hasLength(newPwd) || !StringUtils.hasLength(rePwd)) {
            return Result.error(ContainsStatus.FORM_PARAMS_ERROR);
        }

        //首先判断两次新密码是否一致
        if (!StringUtils.pathEquals(newPwd, rePwd)) {
            return Result.error(ContainsStatus.USER_NEW_PASSWORD_ERROR);
        }

        //从ThreadLocal中获取用户信息
        Map<String, Object> map = ThreadLocalUtil.get();

        //查询用户信息
        User user = userMapper.findByUsername(map.get("username").toString());

        //判断密码是否正确
        if (StringUtils.pathEquals(user.getPassword(), Md5Util.getMD5String(oldPwd))) {
            //密码正确
            //加密新密码
            String md5String = Md5Util.getMD5String(newPwd);
            //设置新密码
            user.setPassword(md5String);
            //更新密码
            userMapper.update(user);
            //从Redis中删除Token
            redisTemplate.delete(ContainsStatus.REDIS_USER_PREFIX + user.getId());
            return Result.success();
        } else {
            //密码错误
            return Result.error(ContainsStatus.USER_PASSWORD_ERROR);
        }
    }
}
